/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.bef.core.action.retrieve;


import com.inspur.edp.bef.api.action.assembler.IMgrActionAssembler;
import com.inspur.edp.bef.api.be.IBEManagerContext;
import com.inspur.edp.bef.api.be.IBusinessEntity;
import com.inspur.edp.bef.api.parameter.retrieve.RetrieveParam;
import com.inspur.edp.bef.api.parameter.retrieve.RetrieveResult;
import com.inspur.edp.bef.core.action.AuthorityUtil;
import com.inspur.edp.bef.core.action.base.ActionUtil;
import com.inspur.edp.bef.core.be.BEContext;
import com.inspur.edp.bef.core.be.BEManagerContext;
import com.inspur.edp.bef.core.be.CoreBEContext;
import com.inspur.edp.bef.core.lock.LockUtils;
import com.inspur.edp.bef.core.scope.BefScope;
import com.inspur.edp.bef.core.session.FuncSessionManager;
import com.inspur.edp.bef.spi.action.AbstractManagerAction;
import com.inspur.edp.cef.entity.entity.IEntityData;
import java.util.List;
import java.util.stream.Collectors;

public class MultiRetrieveMgrAction extends AbstractManagerAction<RetrieveResult> {

		//region Consturctor
	public MultiRetrieveMgrAction(IBEManagerContext managerContext, List<String> idList, RetrieveParam para) {
		super(managerContext);
		ActionUtil.requireNonNull(idList, "idList");
		this.idList = idList;
		this.para = para == null ? new RetrieveParam() : para;
	}
		//endregion

		//region 字段属性
	private List<String> idList;
	private RetrieveParam para;
		//endregion 字段属性

		//region Override

	@Override
	public final void execute() {
		getBEManagerContext().checkAuthority("Retrieve");
		RetrieveUtils.executeBeforeRetrieve(getBEManagerContext(),idList,para);
		List<IBusinessEntity> beList = getBEManagerContext().getEntities(idList,para.getAddDataToCache());

		//① 批量加锁；
		batchLock(beList);

		//② 加锁成功的部分be,执行检索；
		batchRetreve(beList, para);

		//③ 保存检索结果；
		RetrieveResult tempVar = new RetrieveResult();
		tempVar.setDatas(new java.util.LinkedHashMap<>(beList.size()));

		for (IBusinessEntity be : beList) {
			if (para.getNeedLock() && !be.getBEContext().isDeleted() && !be.getBEContext().isLocked()) {
				tempVar.getLockFailedIds().add(be.getID());
			}
			tempVar.getDatas().put(be.getID(), RetrieveUtils.getData(be.getBEContext(), para.getCacheType()));
			if (!para.getAddDataToCache() && !((BEContext)be.getBEContext()).hasChange()){
				((CoreBEContext)be.getBEContext()).clearData();
			}
		}
		setResult(tempVar);
	}

	private void batchLock(List<IBusinessEntity> beList) {
		if (!para.getNeedLock() || !LockUtils.needLock(getBEManagerContext().getModelResInfo())) {
			return;
		}
		BefScope scope = new BefScope(((BEManagerContext)getBEManagerContext()).getSession());
		scope.beginScope();
		try {
			for (IBusinessEntity be : beList) {
				be.addLockWithScope();
			}
			scope.setComplete();
		} catch (Exception e) {
			scope.setAbort();
			throw e;
		}
	}

	@Override
	protected final IMgrActionAssembler getMgrAssembler() {
		return getMgrActionAssemblerFactory().getMultiRetrieveMgrActionAssembler(getBEManagerContext(), para);
	}
		//endregion Override

		//region Private
	private void batchRetreve(List<IBusinessEntity> beList, RetrieveParam para) {
		BefScope scope = new BefScope(((BEManagerContext)getBEManagerContext()).getSession());
		scope.beginScope();
		try
		{
			for (IBusinessEntity be : beList) {
				be.retrieveWithScope(para);
			}
			scope.setComplete();
		}
		catch (java.lang.Exception e) {
			scope.setAbort();
			throw e;
		}
	}

//	private void setRetrieveResult(List<IBusinessEntity> beList)
//	{
//		RetrieveResult tempVar = new RetrieveResult();
//		tempVar.setDatas(new java.util.LinkedHashMap<String, IEntityData>(beList.size()));
//
//		for (IBusinessEntity be : beList) {
//			if (!be.getBEContext().isDeleted() && !be.getBEContext().isLocked()) {
//					tempVar.getLockFailedIds().add(be.getID());
//			}
//			tempVar.getDatas().put(be.getID(), RetrieveUtils.getData(be.getBEContext(), para.getCacheType()));
//		}
//		setResult(tempVar);
//	}

		//endregion
}
